import java.util.ArrayList;
import java.util.Observer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.Observable;

import javax.swing.JOptionPane;

public class TweetPanelModel extends Observable {

	public static ArrayList<TwitterUserModel> twitterUser;

	public static ArrayList<Observer> ObserverCollection = new ArrayList<Observer>();
	public static TweetPanelView tweetPanel = new TweetPanelView();
	public static ArrayList<TwitterUserModel> newTweets;

	public TweetPanelModel() {
	}

	public static void updateTweets() throws InterruptedException,
			ExecutionException {

		if (TwitterFrameView.tweetScrollPane != null) {
			newTweets = getUpdateTweetsMultiThread();
			if (newTweets.size() > 0)
				notifyObserver(newTweets);
			else
				JOptionPane.showMessageDialog(null,
						"No new tweets at this time");
		}
	}

	/**
	 * multi-thread get tweets
	 * 
	 * @throws InterruptedException
	 * @throws ExecutionException
	 * */
	public static ArrayList<TwitterUserModel> getUpdateTweetsMultiThread()
			throws InterruptedException, ExecutionException {
		ArrayList<Callable<TwitterUserModel>> updatedUsers = new ArrayList<Callable<TwitterUserModel>>();
		for (final TwitterUserModel tu : TweetPanelView.twitterUser) {
			if (tu.isTweetNew()) {
				updatedUsers.add(new Callable<TwitterUserModel>() {
					public TwitterUserModel call() {

						return new TwitterUserModel(tu.twitterUserName);
					}
				});
			} else {
				continue;
			}
		}
		final ExecutorService executorPool = Executors
				.newFixedThreadPool(TweetPanelView.twitterUser.size());
		final ArrayList<Future<TwitterUserModel>> updatedUserTweetList = (ArrayList<Future<TwitterUserModel>>) executorPool
				.invokeAll(updatedUsers, 1000, TimeUnit.SECONDS);

		ArrayList<TwitterUserModel> updatedUsersTweets = new ArrayList<TwitterUserModel>();
		for (final Future<TwitterUserModel> newUser : updatedUserTweetList) {
			updatedUsersTweets.add(newUser.get());
		}
		executorPool.shutdown();
		return updatedUsersTweets;
	}

	public static void notifyObserver(ArrayList<TwitterUserModel> newTweets) {
		tweetPanel.update(newTweets);
	}

}
